package com.btlib;


import com.btlib.lib.CarControl;
import com.btlib.lib.MyActivity;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Test extends MyActivity implements SensorEventListener{
  private SensorManager sensorManager;
  private Sensor sensor;
  
  private boolean firstRun = true;
  private boolean connected = false;
  private Orientation original = new Orientation();
  private Orientation old = new Orientation();
  private final int THRESHOLD = 6;
  
  private CarControl cc;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        cc = new CarControl(this);
        sensorManager = (SensorManager)this.getSystemService(SENSOR_SERVICE);
        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        
        Button btn_stop = (Button) findViewById(R.id.btn_stop);
        btn_stop.setOnClickListener(new OnClickListener(){
          @Override
          public void onClick(View arg0) {
            cc.controlStop();
          }
        });
        Button btn_disconn = (Button) findViewById(R.id.btn_disconn);
        btn_disconn.setOnClickListener(new OnClickListener(){
          @Override
          public void onClick(View v) {
            cc.controlDisconnect();
            connected = false;
            firstRun = true;
          }
        });
        Button btn_start = (Button) findViewById(R.id.btn_start);
        btn_start.setOnClickListener(new OnClickListener(){
          public void onClick(View v){
            connected = cc.controlStart();
            Log.e("Test",""+connected);
          }
        });
        
        sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
    }

    /*@Override
    protected void onDestroy() {
      super.onPause();
      sensorManager.unregisterListener(this, sensor);
    }

    @Override
    protected void onResume() {
      super.onResume();
      sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
    }*/

    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      cc.onActivityResult(requestCode, resultCode, data);
    }

    @Override            
    protected void onDestroy() {
      super.onDestroy();
      cc.onDestory();
      sensorManager.unregisterListener(this, sensor);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
    private int distance(final float a, final float b, final int length){
      int x = Math.round(a);
      int y = Math.round(b);
      int dis1 = x - y;
      int dis2 = y - x;
      
      if(dis1 > 0){
        return dis1>length-dis1?length-dis1:dis1;
      }
      else if(dis2 > 0){
        return dis2>length-dis2?length-dis2:dis2;
      }
      else return 0;
    }
    private byte compuSpeed(Orientation newOrientation, int type){
      final int C = 45;
      int dis;
      switch(type){
      case 0:
       dis = distance(newOrientation.roll, original.roll, Orientation.ROLL_LENGTH);
       return (byte)(dis/4 + C);
      case 1:
        dis = distance(newOrientation.pitch, original.pitch, Orientation.PITCH_LENGTH);
        return (byte)(dis/8 + C);
      case 2:
        dis = distance(newOrientation.azimuth, original.azimuth, Orientation.AZIMUTH_LENGTH);
        return (byte)(dis/8 + C);
      }
      return -1;
    }
    @Override
    public void onSensorChanged(SensorEvent event) {
      if(connected){
        if(event.sensor.getType() == Sensor.TYPE_ORIENTATION){
          if(firstRun){
          original.azimuth = event.values[0];
          original.pitch = event.values[1];
          original.roll = event.values[2];
          
          old.azimuth = event.values[0];
          old.pitch = event.values[1];
          old.roll = event.values[2];
          }
          
          firstRun = false;
          if(distance(event.values[0], old.azimuth, Orientation.AZIMUTH_LENGTH) > THRESHOLD
              || distance(event.values[1], old.pitch, Orientation.PITCH_LENGTH) > THRESHOLD
              || distance(event.values[2], old.roll, Orientation.ROLL_LENGTH) > THRESHOLD){
           
            handleOrientAction(new Orientation(event.values[0],event.values[1],event.values[2]));
            
            old.azimuth = event.values[0];
            old.pitch = event.values[1];
            old.roll = event.values[2];
          }
        }
      }
    }
    public void handleOrientAction(Orientation newOrientation){
      int dimension;
      int a = distance(newOrientation.azimuth, original.azimuth, Orientation.AZIMUTH_LENGTH);
      int b = distance(newOrientation.pitch, original.pitch, Orientation.PITCH_LENGTH);
      int c = distance(newOrientation.roll, original.roll, Orientation.ROLL_LENGTH);
      Log.e("Bluetooth","a="+a+"b="+b+"c="+c);
      if(a >= b && a >= c)
        dimension = 0;
      else if(b >= a && b >= c)
        dimension = 1;
      else
        dimension = 2;
      
      switch(dimension){
      case 0:
        cc.controlFoward((byte)45);
        break;
      case 1:
        if(newOrientation.pitch > original.pitch)
          cc.controlLeft(compuSpeed(newOrientation, 1));
        else
          cc.controlRight(compuSpeed(newOrientation, 1));
        break;
      case 2:
        if(newOrientation.roll > original.roll)
          cc.controlFoward(compuSpeed(newOrientation, 0));
        else
          cc.controlBackword(compuSpeed(newOrientation, 0));
        break;
      }
      
    }
    private class Orientation{
      public static final int AZIMUTH_LENGTH = 360;
      public static final int PITCH_LENGTH = 360;
      public static final int ROLL_LENGTH = 180;
      
      public Orientation(){}
      public Orientation(float azimuth, float pitch, float roll){
        this.azimuth = azimuth;
        this.pitch = pitch;
        this.roll = roll;
      }
      public float azimuth;
      public float pitch;
      public float roll;
      
    }
    @Override
    public void endConnect() {
      // TODO Auto-generated method stub
      
    }
}